﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace AlarmClock.DAL
{
    public class ClockService
    {
        private string appPath = AppDomain.CurrentDomain.BaseDirectory;

        #region 创建

        /// <summary>
        /// 创建一个xml文档（路径不全的情况下默认保存在debug文件夹中）
        /// </summary>
        /// <param name="XMLPath">文件路径。默认：Clocks.xml</param>
        /// <param name="rootName">根节点名称。默认：Clocks</param>
        public void CreateClocksXML(string XMLPath = "Clocks.xml")
        {
            XMLPath = Path.Combine(appPath, XMLPath);
            //<?xml version="1.0" encoding="utf-8" standalone="yes"?>
            //加头
            XmlDocument xDoc = new XmlDocument();
            xDoc.AppendChild(xDoc.CreateXmlDeclaration("1.0", "utf-8", "yes"));

            //加入根元素:Root
            XmlElement root = xDoc.CreateElement("Root");
            xDoc.AppendChild(root);

            //ClockConfig:配置信息:Root/ClockConfig
            XmlElement Config = xDoc.CreateElement("ClockConfig");//创建新的子节

            root.AppendChild(Config);

            //Clocks：闹钟信息集合:Root/Clocks
            XmlElement Clocks = xDoc.CreateElement("Clocks");//创建新的子节点
            root.AppendChild(Clocks);

            xDoc.Save(XMLPath);
        }
        #endregion

        #region 新增

        /// <summary>
        /// 增加新数据到xml文档中（路径不全的情况下默认添加在debug文件夹中）
        /// </summary>
        /// <param name="clock">新数据</param>
        /// <param name="XMLPath">文件路径。默认：Clocks.xml</param>
        public void InsertClock(Entity.Clock clock, string XMLPath = "Clocks.xml")
        {
            XMLPath = Path.Combine(appPath, XMLPath);
            if (!File.Exists(XMLPath)) CreateClocksXML(XMLPath);//不存在就创建

            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(XMLPath);
            XmlElement root = xDoc.DocumentElement;//获取已有的根节点

            XmlNode Clocks = xDoc.SelectSingleNode("Root/Clocks");

            //创建新的子节点
            XmlElement curClock = xDoc.CreateElement(clock.ClockName);
            curClock.SetAttribute("time", clock.ClockInfo.time);
            curClock.SetAttribute("repeat", clock.ClockInfo.repeat);
            curClock.SetAttribute("music", clock.ClockInfo.music);
            curClock.SetAttribute("things", clock.ClockInfo.things);
            curClock.SetAttribute("nextInterval", clock.ClockInfo.nextInterval);
            curClock.SetAttribute("musicVolume", clock.ClockInfo.musicVolume);
            curClock.SetAttribute("musicPlus", clock.ClockInfo.musicPlus);
            curClock.SetAttribute("isActive", clock.ClockInfo.isActive);

            Clocks.AppendChild(curClock);//根节点 附加新子节点。

            xDoc.Save(XMLPath);
        }

        #endregion

        #region 删除

        /// <summary>
        /// 删除xml文档的指定数据（路径不全的情况下默认删除在debug文件夹中）
        /// </summary>
        /// <param name="clock">指定数据</param>
        /// <param name="XMLPath">文件路径。默认：Clocks.xml</param>
        public void DeleteClock(Entity.Clock clock, string XMLPath = "Clocks.xml")
        {
            XMLPath = Path.Combine(appPath, XMLPath);
            if (File.Exists(XMLPath))
            {
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(XMLPath);
                XmlElement root = xDoc.DocumentElement;//获取已有的根节点

                //Root/Clocks/Clock[1-100]
                XmlNode parentNode = xDoc.SelectSingleNode(root.Name + "/Clocks");//找到父节点
                XmlNode targetNode = xDoc.SelectSingleNode(root.Name + "/Clocks/" + clock.ClockName);//查找目标子节点
                parentNode.RemoveChild(targetNode);//父节点删除目标子节点
                xDoc.Save(XMLPath);
            }
        }


        #endregion

        #region 查询

        /// <summary>
        /// 读取全部闹钟数据
        /// </summary>
        /// <param name="XMLPath">文件路径。默认：Clocks.xml</param>
        /// <param name="rootName">根节点名称。默认：Clocks</param>
        /// <returns></returns>
        public List<Entity.Clock> ReadAllClockInfo(string XMLPath = "Clocks.xml", string subRootName = "Clocks")
        {
            XMLPath = Path.Combine(appPath, XMLPath);
            if (!File.Exists(XMLPath)) return new List<Entity.Clock>();

            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(XMLPath);

            XmlNode root = xDoc.SelectSingleNode("Root/"+subRootName);//获取根节点:没有东西会是null
            if (root == null) return new List<Entity.Clock>();

            XmlNodeList nodeList = root.ChildNodes;

            List<Entity.Clock> clocks_List = new List<Entity.Clock>();//闹钟列表
            Entity.Clock clock;

            foreach (XmlNode node in nodeList)//闹钟
            {
                XmlElement curClock = (XmlElement)node;
                clock = new Entity.Clock()
                {
                    ClockName = curClock.Name,//闹钟名称
                    ClockInfo = new Entity.ClockInfo()//闹钟的详细信息
                    {
                        time = curClock.GetAttribute("time"),
                        repeat = curClock.GetAttribute("repeat"),
                        music = curClock.GetAttribute("music"),
                        things = curClock.GetAttribute("things"),
                        nextInterval = curClock.GetAttribute("nextInterval"),
                        musicVolume = curClock.GetAttribute("musicVolume"),
                        musicPlus = curClock.GetAttribute("musicPlus"),
                        isActive=curClock.GetAttribute("isActive")
                    }
                };

                clocks_List.Add(clock);//添加闹钟
            }

            return clocks_List;
        }

        /// <summary>
        /// 读取全局配置信息
        /// </summary>
        /// <param name="XMLPath">文件路径。默认：Clocks.xml</param>
        /// <param name="rootName">根节点名称。默认：Clocks</param>
        /// <returns></returns>
        public Entity.ClockConfig ReadAllClockConfig(string XMLPath = "Clocks.xml", string rootName = "ClockConfig")
        {
            XMLPath = Path.Combine(appPath, XMLPath);
            if (!File.Exists(XMLPath)) CreateClocksXML();

            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(XMLPath);

            XmlNode TargetNode = xDoc.SelectSingleNode("Root/"+rootName);//获取配置信息节点       
            XmlElement ClockConfig = (XmlElement)TargetNode;       

            var AllClockConfig = new Entity.ClockConfig()
            {
                recentTime = string.IsNullOrEmpty(ClockConfig.GetAttribute("recentTime")) ?
                                DateTime.Now.AddMinutes(-1).ToString("yyyy-MM-dd HH:mm:ss") : ClockConfig.GetAttribute("recentTime"),

                clockCount = string.IsNullOrEmpty(ClockConfig.GetAttribute("clockCount")) ?
                                "0" : ClockConfig.GetAttribute("clockCount"),

                clockMaxNum = string.IsNullOrEmpty(ClockConfig.GetAttribute("clockMaxNum")) ?
                                "100" : ClockConfig.GetAttribute("clockMaxNum"),
                appAutoStart = string.IsNullOrEmpty(ClockConfig.GetAttribute("appAutoStart")) ?
                                false : bool.Parse(ClockConfig.GetAttribute("appAutoStart")),
                isExitToMiniMode = string.IsNullOrEmpty(ClockConfig.GetAttribute("isExitToMiniMode")) ?
                                false : bool.Parse(ClockConfig.GetAttribute("isExitToMiniMode")),
                alarmingShowWeather = string.IsNullOrEmpty(ClockConfig.GetAttribute("alarmingShowWeather")) ?
                                false : bool.Parse(ClockConfig.GetAttribute("alarmingShowWeather")),
                createDeskShortCut = string.IsNullOrEmpty(ClockConfig.GetAttribute("createDeskShortCut")) ?
                                false : bool.Parse(ClockConfig.GetAttribute("createDeskShortCut")),
            };

            //没有配置信息，更新配置信息
            if (ClockConfig.FirstChild == null) 
                UpdateClockConfig(AllClockConfig);

            return AllClockConfig;         
        }

        #endregion

        #region 修改

        /// <summary>
        /// 修改指定闹钟数据（路径不全的情况下默认更新在debug文件夹中）
        /// </summary>
        /// <param name="clock">指定数据</param>
        /// <param name="XMLPath">文件路径。默认：Clocks.xml</param>
        public void UpdateClock(Entity.Clock clock, string XMLPath = "Clocks.xml")
        {
            XMLPath = Path.Combine(appPath, XMLPath);
            XmlDocument xDoc = new XmlDocument();
            if (!File.Exists(XMLPath)) InsertClock(clock, XMLPath);
            else
            {
                xDoc.Load(XMLPath);
                XmlElement root = xDoc.DocumentElement;//获取已有的根节点

                XmlNode targetNode = xDoc.SelectSingleNode("Root/Clocks/" + clock.ClockName);
                XmlElement curNode = (XmlElement)targetNode;
                curNode.SetAttribute("time", clock.ClockInfo.time);
                curNode.SetAttribute("repeat", clock.ClockInfo.repeat);
                curNode.SetAttribute("music", clock.ClockInfo.music);
                curNode.SetAttribute("things", clock.ClockInfo.things);
                curNode.SetAttribute("nextInterval", clock.ClockInfo.nextInterval);
                curNode.SetAttribute("musicVolume", clock.ClockInfo.musicVolume);
                curNode.SetAttribute("musicPlus", clock.ClockInfo.musicPlus);
                curNode.SetAttribute("isActive", clock.ClockInfo.isActive);
                xDoc.Save(XMLPath);
            }
        }

        /// <summary>
        /// 修改闹钟全局配置数据
        /// </summary>
        /// <param name="Config"></param>
        /// <param name="XMLPath"></param>
        public void UpdateClockConfig(Entity.ClockConfig Config, string XMLPath = "Clocks.xml")
        {
            XMLPath = Path.Combine(appPath, XMLPath);
            if (!File.Exists(XMLPath)) CreateClocksXML(XMLPath);

            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(XMLPath);
            XmlElement root = xDoc.DocumentElement;//获取已有的根节点

            //配置更新
            XmlNode targetNode = xDoc.SelectSingleNode("Root/ClockConfig");
            XmlElement curNode = (XmlElement)targetNode;
            curNode.SetAttribute("recentTime", Config.recentTime);
            curNode.SetAttribute("clockCount", Config.clockCount);
            curNode.SetAttribute("clockMaxNum", Config.clockMaxNum);
            curNode.SetAttribute("appAutoStart", Config.appAutoStart.ToString());
            curNode.SetAttribute("isExitToMiniMode", Config.isExitToMiniMode.ToString());
            curNode.SetAttribute("alarmingShowWeather", Config.alarmingShowWeather.ToString());
            curNode.SetAttribute("createDeskShortCut", Config.createDeskShortCut.ToString());

            xDoc.Save(XMLPath);

        }

        #endregion

    }
}
